package com.app.service.impl;

import com.app.common.AppException;
import com.app.dao.IUserDao;
import com.app.dao.impl.UserDao;
import com.app.pojo.User;
import com.app.service.IUserService;
import com.app.utils.UtilTools;

import java.util.ArrayList;
import java.util.List;

/**
 * Copyright (C) @2020 fgwang.660@gmail.com
 *
 * @author witt
 * @version 1.0
 * @className UserService
 * @date 2020-06-14 17:22
 * @description User  用户业务逻辑实现
 */
public class UserService implements IUserService {

	/**
	 * 业务逻辑层注入数据持久层
	 */
	private final IUserDao dao = new UserDao();

	/**
	 * 注册方法
	 *
	 * @param loginId
	 * @param password
	 * @return
	 */
	@Override
	public User login(String loginId, String password) {
		// 校验
		if (UtilTools.isEmpty(loginId)) throw new AppException("登录用户名不能为空！");
		if (UtilTools.isEmpty(password)) throw new AppException("登录密码不能为空！");

		// 通过账户查用户

		User user = this.loadUserByLoginId(loginId);

		// 用户不存在
		if (UtilTools.isEmpty(user)) throw new AppException("用户不存在！");

		// 账户被停用
		if (user.getDisable()) throw new AppException("该账户已停用，请联系管理员！");

		// 密码比对
		if (! user.getPassword().equals(UtilTools.MD5Encoded(password)))
			throw new AppException("密码输入错误，请重新登录！");

		// 登录成功
		return user;
	}

	/**
	 * 注册用户
	 *
	 * @param loginId       用户名
	 * @param password      密码
	 * @param passwordAgain 确认密码
	 * @return 新增id
	 */
	@Override
	public Integer register(String loginId, String password, String passwordAgain) {
		if (UtilTools.isAllEmpty(loginId, password, passwordAgain)) throw new AppException("注册用户名或密码不能为空！");
		if (loginId.length() < 6 || loginId.length() > 18) {
			throw new AppException("用户名必须在 6-18 位之间");
		}

		if (password.length() < 6 || password.length() > 22) {
			throw new AppException("密码长度必须在 6-22 位之间");
		}

		if (! password.equals(passwordAgain)) {
			throw new AppException("密码和确认密码不一致！");
		}

		// 查询用户是否已经注册
		User user = loadUserByLoginId(loginId);
		if (UtilTools.isNotEmpty(user)) {
			throw new AppException("用户名已经被注册");
		}

		// 构建新用户
		user = new User()
				.setLoginId(loginId)
				.setPassword(UtilTools.MD5Encoded(password));

		// 新增并返回
		return add(user);
	}

	/**
	 * 查询用户，通过loginId
	 *
	 * @param loginId loginId
	 * @return User对象
	 */
	@Override
	public User loadUserByLoginId(String loginId) {
		if (UtilTools.isEmpty(loginId)) throw new AppException("用户账户不能为空！");
		return dao.select(loginId);
	}

	/**
	 * 查询全部数据集合
	 *
	 * @return
	 */
	@Override
	public List<User> get() {
		List<User> users = dao.select();
		return UtilTools.isEmpty(users) ? new ArrayList<>() : users;
	}

	/**
	 * 根据id查询单条数据
	 *
	 * @param id 主键Id
	 * @return 数据对象
	 */
	@Override
	public User get(Integer id) {
		if (UtilTools.isEmpty(id)) throw new AppException("查询id不能为空！");
		User user = dao.select(id);
		if(UtilTools.isEmpty(user)) throw new AppException("该用户已经被删除，请重新绑定！");
		return user;
	}

	/**
	 * 新增数据
	 *
	 * @param obj 数据对象
	 * @return 主键id
	 */
	@Override
	public Integer add(User user) {
		if (UtilTools.isEmpty(user)) throw new AppException("新增对象不能为空！");
		if (UtilTools.isEmpty(user.getLoginId())) throw new AppException("用户名不能为空！");
		if (UtilTools.isEmpty(user.getPassword())) throw new AppException("密码不能为空！");

		return dao.insert(user);
	}

	/**
	 * 更新数据
	 *
	 * @param obj 更新数据对象
	 */
	@Override
	public void update(User user) {
		if (UtilTools.isEmpty(user)) throw new AppException("更新对象为空！");
		if (UtilTools.isEmpty(user.getId())) throw new AppException("更新对象主键为空！");

		dao.update(user);
	}

	/**
	 * 删除数据，支持批量
	 *
	 * @param ids 删除的主键，例如 1,2,3,4  可以批量
	 */
	@Override
	public void delete(String ids) {
		if (UtilTools.isEmpty(ids)) throw new AppException("删除标识不能为空！");
		dao.delete(ids);
	}

	/**
	 * 重置密码
	 *
	 * @param login_id
	 * @return
	 */
	@Override
	public String resetPassword(String login_id) {
		if(UtilTools.isEmpty(login_id)) throw new AppException("请先输入用户名，再点击'忘记密码'！");
		User user = loadUserByLoginId(login_id);
		if(UtilTools.isEmpty(user)) throw new AppException("未查询到需要重置密码的用户，请确认账户是否填写正确！");

		// 生成随机密码
		String newPassword = UtilTools.randomString(8);

		// 加密密码
		String encodedPwd = UtilTools.MD5Encoded(newPassword);
		// 把新密码给当前用户
		user.setPassword(encodedPwd);

		// 去库中把数据改掉
		dao.update(user);

		// 切忌 返回 【未加密】的密码给用户
		return newPassword;
	}
}
